package br.com.os2.pacemark.dao;

import br.com.os2.pacemark.model.Paciente;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * Classe PacienteDAO, extende a classe DAOGenerico para obeter 
 * recursos de conexão e excução de consultas e comandos.
 * 
 * Responsável por gerenciar acesso ao banco de dados relacionados a 
 * Entidade Paciente.
 * 
 * @author Daniel
 * 
 */
public class PacienteDAO extends DAOGenerico{
    
    /**
     * Método para inserir um paciente.
     * 
     * @param paciente Objeto paciente a ser inserido.
     * @return boolean indica se o método foi executado com sucesso.
     * 
     **/
    
    public boolean inserir(Paciente paciente){
     
        paciente.setId(getNextId("pacientes"));
        
        return executarComando("INSERT INTO pacientes (id, nome, endereco_id, contato_id, documento_id) "
                             + "VALUES (?,?,?,?,?)"
                             , paciente.getId()
                             , paciente.getNome(), paciente.getEndereco().getId()
                             , paciente.getContato().getId(), paciente.getDocumento().getId());
        
    }
    
    /**
     * Método para atualizar informações de um paciente.
     * 
     * @param paciente Objeto paciente a ser atualizado.
     * @return boolean indica se o método foi executado com sucesso
     * 
     **/
    
    public boolean atualizar(Paciente paciente){
     
        return executarComando("UPDATE pacientes SET nome = ?, endereco_id = ?, "
                             + "contato_id = ?, documento_id = ? WHERE id = ?"
                             , paciente.getNome(), paciente.getEndereco().getId()
                             , paciente.getContato().getId()
                             , paciente.getDocumento().getId(), paciente.getId());
        
    }
    
    /**
     * Método para excluir um paciente.
     * 
     * @param paciente Objeto paciente a ser excluído.
     * @return boolean indica se o método foi executado com sucesso
     * 
     **/
    
    public boolean excluir(Paciente paciente){
    
        return executarComando("DELETE FROM pacientes WHERE id = ?", paciente.getId());
        
    }
    
    /**
     * Método para excluir um paciente.
     * 
     * @param id ID do objeto a ser excluído
     * @return boolean indica se o método foi executado com sucesso
     * 
     **/
    
    public boolean excluir(int id){
    
        return executarComando("DELETE FROM pacientes WHERE id = ?", id);
        
    }
    
    /**
     * Método para buscar o paciente pelo ID
     * 
     * @return Paciente correspondente ai ID, se não for encontrado retorna null.
     * 
     * @param id inteiro que representa o ID do paciente na tabela
     * 
     **/
    
    public Paciente getById(int id){
    
        ResultSet rs = executarConsulta("SELECT * FROM pacientes WHERE id = ?", id);
        
        Paciente paciente = null;
        
        try {
            
             //DAO's necessários para preencher informações do Paciente
            
            ContatoDAO contatoDAO = new ContatoDAO();
            EnderecoDAO enderecoDAO = new EnderecoDAO();
            DocumentoDAO documentoDAO = new DocumentoDAO();
            
            if(rs.next()){
                
                paciente = polularInformacoes(rs, contatoDAO, enderecoDAO, documentoDAO);
                
            }
            
        } catch (SQLException ex) {
            
            System.err.println("ERRO AO BUSCAR PACIENTE POR ID");
            
        }finally{
            
            try {
                
                rs.close();
                connection.close();
                
            } catch (SQLException ex) {
                
                
                
            }
            
        }
        
        return paciente;
        
    }
    
    /**
     * Método para listagem de pacientes.
     * 
     * @return Retorna uma lista de pacientes com o resultado da consulta
     * 
     **/
    
    public List<Paciente> listar(){
    
        List<Paciente> pacientes = new ArrayList<>();
        
        ResultSet rs = executarConsulta("SELECT * FROM pacientes");
        
        try {
            
            //DAO's necessários para preencher informações do Paciente
            
            ContatoDAO contatoDAO = new ContatoDAO();
            EnderecoDAO enderecoDAO = new EnderecoDAO();
            DocumentoDAO documentoDAO = new DocumentoDAO();
            
            while(rs.next()){
                
                pacientes.add(polularInformacoes(rs, contatoDAO, enderecoDAO, documentoDAO));
                
            }
            
        } catch (SQLException ex) {
            
            System.err.println("ERRO AO PERCORER RESULT_SET");
            
        }finally{
            
            try {
                
                rs.close();
                connection.close();
                
            } catch (SQLException ex) {
                
                
                
            }
            
        }
            
        return pacientes;
        
    }
    
    /**
     * Método para pesquisar pacientes por nome.
     *
     * Retorna um ResultSet com os resultados
     *
     * @param nome Variável para pesquisa
     *
     *
     */
    public List<Paciente> listar(String nome) {

        List<Paciente> pacientes = new ArrayList<>();

        ResultSet rs = executarConsulta("SELECT * FROM pacientes "
                                      + "WHERE UPPER(nome) LIKE ? "
                                      + "ORDER BY id", "%" + nome.toUpperCase() + "%");

        try {

            //DAO's necessários para preencher informações do Paciente
            ContatoDAO contatoDAO = new ContatoDAO();
            EnderecoDAO enderecoDAO = new EnderecoDAO();
            DocumentoDAO documentoDAO = new DocumentoDAO();

            while (rs.next()) {

                pacientes.add(polularInformacoes(rs, contatoDAO, enderecoDAO, documentoDAO));

            }

        } catch (SQLException ex) {

            System.err.println("ERRO AO PERCORER RESULT_SET");

        } finally {

            try {

                rs.close();
                connection.close();

            } catch (SQLException ex) {

            }

        }

        return pacientes;

    }
    
    /**
     * Método para preencher informações de um paciente com resultados do 
     * banco de dados.
     * 
     * @param rs ResultSet com o resultado de uma consulta SQL
     * 
     * @param contatoDAO DAO de Contato
     * 
     * @param enderecoDAO DAO de Endereco
     * 
     * @param documentoDAO DAO de Documento
     * 
     * @return Retorna um paciente populado com informações vindas do banco de 
     *  dados
     * 
     **/
    
    public Paciente polularInformacoes(ResultSet rs, ContatoDAO contatoDAO,
                                       EnderecoDAO enderecoDAO, DocumentoDAO documentoDAO){
    
        Paciente paciente = new Paciente();
        
        try {
            
            paciente.setId(rs.getInt("id"));
            paciente.setNome(rs.getString("nome"));
            paciente.setContato(contatoDAO.getById(rs.getInt("contato_id")));
            paciente.setEndereco(enderecoDAO.getById(rs.getInt("endereco_id")));
            paciente.setDocumento(documentoDAO.getById(rs.getInt("documento_id")));
            
        } catch (SQLException ex) {
            
            System.err.println("ERRO AO PULULAR PACIENTE");
            
        }
        
        return paciente;
        
    }
    
}

